package cn.elead.chaos.sso.server.config;

import java.util.List;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import cn.elead.chaos.core.constant.ModuleCons;
import cn.elead.chaos.framework.properties.ChaosProperties;
import cn.elead.chaos.framework.properties.Sso;
import cn.elead.chaos.framework.web.enums.EnumScan;
import cn.elead.chaos.sso.core.constant.SsoConstant;
import cn.elead.chaos.sso.core.filter.SsoWebFilter;
import cn.elead.chaos.sso.core.handler.LoginSuccessHandler;
import cn.elead.chaos.sso.server.handler.LoginSuccessHandlerImpl;
import cn.elead.chaos.sso.server.properties.SsoProperties;
import cn.elead.chaos.sso.server.web.login.resolve.LgoinFormParamArgumentResolver;
import cn.hutool.crypto.asymmetric.RSA;

/**
 * <p>
 * Epom项目SpringBoot相关配置
 * </p>
 *
 * @author luopeng
 * @since 2017-09-21
 */
@Configuration
//表示通过aop框架暴露该代理对象,AopContext能够访问
@EnableAspectJAutoProxy(exposeProxy = true)
@EnumScan("cn.elead.chaos.sso.server.enums")
@ComponentScan(ModuleCons.CHAOS_PACKAGE)
@MapperScan(SsoAuoConfiguration.BASE_DAO_PACKAGE)
@EnableConfigurationProperties(SsoProperties.class)
public class SsoAuoConfiguration implements WebMvcConfigurer {

	public static final String BASE_PACKAGE = ModuleCons.CHAOS_PACKAGE + ".sso.server";

	public static final String BASE_DAO_PACKAGE = BASE_PACKAGE + ".**.mapper";

	@Autowired
	private ChaosProperties chaos;

	@Override
	public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
		// https://www.licoy.cn/3238.html
		argumentResolvers.add(new LgoinFormParamArgumentResolver());
	}

	@Override
	public void addResourceHandlers(ResourceHandlerRegistry registry) {

		/** 本地文件上传路径 */
		String uploadPath = chaos.getPath().getFilePath();
		// 头像
		String resourcePrefix = chaos.getPath().getResourcePrefix();
		String avatar = chaos.getPath().getPrefix().getAvatar();
		registry.addResourceHandler(resourcePrefix + avatar + "profile/**").addResourceLocations("file:" + uploadPath + avatar + "profile/");

		/** swagger配置 */
		registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
		registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
	}

	/**
	 * 单点登录成功回调
	 * 
	 * @return
	 */
	@Bean
	public LoginSuccessHandler loginSuccessHandler() {
		return new LoginSuccessHandlerImpl();
	}

	@Bean
	public RSA ras() {
		RSA rsa = new RSA(chaos.getPwd().getPrivateKey(), chaos.getPwd().getPublicKey());
		return rsa;
	}

	@Bean
	public FilterRegistrationBean<SsoWebFilter> SsoFilterRegistration() {

		FilterRegistrationBean<SsoWebFilter> registration = new FilterRegistrationBean<SsoWebFilter>();

		registration.setName("SsoOauthFilter");
		registration.setOrder(1);
		registration.addUrlPatterns("/system/*", "/monitor/*");

		SsoWebFilter ssoWebFilter = new SsoWebFilter();
		ssoWebFilter.setLoginSuccessHandler(loginSuccessHandler());
		registration.setFilter(ssoWebFilter);

		Sso sso = chaos.getSso();
		registration.addInitParameter(SsoConstant.SSO_SERVER, sso.getServer());
		registration.addInitParameter(SsoConstant.PARAM_CLIENT_ID, sso.getClientId()); // 单点退出路径
		registration.addInitParameter(SsoConstant.SSO_CLIENT_SECRET, sso.getClientSecret()); // 通过token换取token说
		registration.addInitParameter(SsoConstant.SSO_LOGOUT, sso.getLogout()); // 前端配置获取用户信息的路径
		registration.addInitParameter(SsoConstant.PARAM_RESPONSE_TYPE, sso.getResponseType());

		return registration;
	}

}